<?php
/**
 * APP端用户登录
 * User: dxk <duxiaokong@sina.com>
 * Date: 2023/3/25 17:28
 */

namespace App\OpenApi\AppApi\Passport;

use App\Library\Service\Captcha;
use App\Library\Service\SMSSend;
use App\Library\Service\Verify;
use App\Model\Core\User\UserModel;
use App\Service\AppPush\DeviceBindService;
use App\Service\Auth\AppAuthService;
use App\Service\Core\Service\Order\OrderProductService;
use App\Service\Core\User\User\UserService;
use App\Service\OpenApi\AppApi\OpenBaseApi;
use App\Service\OpenApi\H5AutoLoginCheckService;
use App\Service\ParamsService;
use Gregwar\Captcha\CaptchaBuilder;

class LoginApi extends OpenBaseApi
{
    /**
     * 获取验证码
     * @return array
     */
    public function sendCode(): array
    {
        $mobile = trim($this->input('mobile'));
        if (!Verify::isMobile($mobile)) {
            return alert_info(1, '请输入正确的手机号');
        }
//        $user = UserModel::getInstance()->getOneByMobile($mobile);
//        if (empty($user)) {
//            return alert_info(1, '账号不存在');
//        }
        $SMS = new SMSSend();
        $res = $SMS->sendCaptcha($mobile, config('sys.aliyun.sms_tpl_login'));
        if (!isset($res['code']) || $res['code'] !== 0) {
            return alert_info(1, '短信发送失败,' . $res['msg']);
        }
        return alert_info(0, '短信发送成功');
    }

    /**
     * 获取图片验证码
     * @return array
     */
    public function imgCode(): array
    {
        $width = intval($this->input('width', 100));
        $height = intval($this->input('height', 50));
        $new_code = easy_random(4);
        $builder = new CaptchaBuilder($new_code);
        $builder->setDistortion(false)
            ->setBackgroundColor(229, 229, 229)
            ->build($width, $height);
        Captcha::storeCaptcha($builder->getPhrase());
        return alert_info(0, 'ok', [
            'code' => $new_code,
            'captcha' => $builder->inline(),
        ]);
    }

    /**
     * 第三方app免登录
     * @return array
     */
    public function appAutoLogin(): array
    {
        $auto_login_param = trim($this->input('auto_login_param'));
        $auto_login = function () use ($auto_login_param) {
            if (empty($auto_login_param)) {
                return alert_info(1, '免登录参数错误');
            }
            $auto_login_param = json_decode(base64_decode($auto_login_param), true);
            if (!is_array($auto_login_param)) {
                return alert_info(1, "免登录参数解析错误");
            }
            $login_check_res = (new H5AutoLoginCheckService())->autoLoginCheck($auto_login_param);
            if ($login_check_res['code'] !== 0) {
                return alert_info($login_check_res['code'], '免登录参数检测失败,' . $login_check_res['msg']);
            }
            $login_res = $this->loginByMobile($auto_login_param['mobile'], '', ['is_third_login' => 1, 'third_app_key' => $auto_login_param['app_key']]);
            $user_info = $login_res['data']['user_info'];
            $user_id = $user_info['user_id'];
            if ($auto_login_param['service_code']) {
                //传入激活码，自动激活服务卡
                $active_res = OrderProductService::getInstance()->activeByServiceCode($auto_login_param['service_code'], $user_id, $user_info['mobile']);
                easy_log('auto_login_active', ['auto_login_param' => $auto_login_param, 'login_res' => $login_res, 'active_res' => $active_res]);
            }
            $third_app = $login_check_res['data']['app'];
            $user_info['third_app_key'] = $auto_login_param['app_key'];
            $user_info['third_app_type'] = $third_app['app_type'];
            $user_info['show_mall'] = $third_app['use_mall'];
            $user_info['third_app_use_hehuen'] = $third_app['use_hehuen'];
            $login_res['data']['user_info'] = $user_info;
            return $login_res;
        };
        $auto_login_res = $auto_login();
        return alert_info(0, $auto_login_res['msg'], array_merge($auto_login_res['data'], ['sub_code' => $auto_login_res['code']]));
    }

    /**
     * @return array
     */
    public function login(): array
    {
        $mobile = trim($this->input('mobile'));
        $vcode = trim($this->input('vcode'));
        $device_id = trim($this->input('device_id'));
        if (empty($mobile)) {
            return alert_info(1, '手机号为空');
        }
        //校验短信验证码
        $SMS = new SMSSend();
        $res = $SMS->verifyCaptcha($mobile, config('sys.aliyun.sms_tpl_login'), $vcode);
        if (!$res) {
            if (in_array($mobile, ['18610929262', '13693137172',/*自己测试使用*/ '13681029724', '13269062867', '13691225763', '15133064364', '18510981152'])) {//测试忽略短信验证
                if ($vcode != '888888') {
                    return alert_info(1, '手机验证码错误,请重新获取验证码01');
                }
            } else {
                return alert_info(1, '手机验证码错误,请重新获取验证码');
            }
        }
        $login_res = $this->loginByMobile($mobile, $device_id);
        $login_res['data']['user_info']['show_mall'] = 1;
        return $login_res;
    }

    /**
     * 根据手机号登录
     * @param string $mobile
     * @param $device_id
     * @param array $params
     * @return array
     */
    private function loginByMobile(string $mobile, $device_id, array $params = []): array
    {
        $user = UserModel::getInstance()->getOneByMobile($mobile);
        //==============不存在则自动注册用户
        if (empty($user)) {
            $user_id = UserModel::getInstance()->addOne([
                'username' => '手机用户' . substr($mobile, -4) . '_' . easy_random(5, 'abcdefghijkmnpqrstuvwxyz'),
                'mobile' => $mobile,
                'status' => ParamsService::STATUS_ENABLE,
                'created_at' => date('Y-m-d H:i:s'),
                'created_by' => $mobile,
                'updated_at' => date('Y-m-d H:i:s'),
                'updated_by' => $mobile,
            ]);
            if ($user_id === false) {
                return alert_info(1, "自动注册用户失败");
            }
            $user = UserModel::getInstance()->getOne($user_id);
            if (empty($user)) {
                return alert_info(1, "获取用户信息失败");
            }
        }
        //获取扩展信息
        $UserService = UserService::getInstance();
        $user = $UserService->getExtInfo($user);
        $user_id = $user['user_id'];
        $res = AppAuthService::login($user_id);
        if ($res['code'] !== 0) {
            return $res;
        }
        $auth_res = (new \App\Service\OpenApi\AppApi\AppAuthService($this->app_key))->auth($user_id, array_merge(['device_id' => $device_id], $params));
        if ($auth_res['code'] !== 0) {
            return alert_info(1, '用户授权失败,' . $auth_res['msg']);
        }
        //绑定设备
        (new DeviceBindService($this->app_key))->appLogin($user_id, $device_id);
        return alert_info(0, '登录成功', [
            'access_token' => $auth_res['data']['access_token'],
            'user_info' => $user,
        ]);
    }

    /**
     *
     * @return array
     */
    public function logout(): array
    {
        (new \App\Service\OpenApi\AppApi\AppAuthService($this->app_key))->cancelAuth($this->operate_id);
        //解绑设备
        (new DeviceBindService($this->app_key))->appLoginOut($this->operate_id, $this->device_id);
        return alert_info(0, '退出成功');
    }
}
